import { MeshBasicMaterial, MeshBasicMaterialParameters } from "three/src/materials/MeshBasicMaterial";
import MaterialAdapter from "./MaterialAdapter";
import { LineBasicMaterial, LineBasicMaterialParameters, LineDashedMaterial, LineDashedMaterialParameters, MeshDepthMaterial, MeshDepthMaterialParameters, MeshLambertMaterial, MeshLambertMaterialParameters, MeshNormalMaterial, MeshNormalMaterialParameters, MeshPhongMaterial, MeshPhongMaterialParameters, MeshPhysicalMaterial, MeshPhysicalMaterialParameters, MeshStandardMaterial, MeshStandardMaterialParameters, MeshToonMaterial, MeshToonMaterialParameters, PointsMaterial, PointsMaterialParameters } from "three";

export class CustomMeshBasicMaterial extends MeshBasicMaterial{

    public constructor(materialParam: {coreParameters?: MeshBasicMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshPhongMaterial extends MeshPhongMaterial{

    public constructor(materialParam: {coreParameters?: MeshPhongMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshLambertMaterial extends MeshLambertMaterial{

    public constructor(materialParam: {coreParameters?: MeshLambertMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshStandardMaterial extends MeshStandardMaterial{

    public constructor(materialParam: {coreParameters?: MeshStandardMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshToonMaterial extends MeshToonMaterial{

    public constructor(materialParam: {coreParameters?: MeshToonMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshPhysicalMaterial extends MeshPhysicalMaterial{

    public constructor(materialParam: {coreParameters?: MeshPhysicalMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshNormalMaterial extends MeshNormalMaterial{

    public constructor(materialParam: {coreParameters?: MeshNormalMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomPointsMaterial extends PointsMaterial{

    public constructor(materialParam: {coreParameters?: PointsMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomMeshDepthMaterial extends MeshDepthMaterial{

    public constructor(materialParam: {coreParameters?: MeshDepthMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomLineBasicMaterial extends LineBasicMaterial{

    public constructor(materialParam: {coreParameters?: LineBasicMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}

export class CustomLineDashedMaterial extends LineDashedMaterial{

    public constructor(materialParam: {coreParameters?: LineDashedMaterialParameters, macrosList?: Array<string>, identity?: string}) {
        if(materialParam){
             super(materialParam.coreParameters);
        }else{
            super(null);
        }

        let materialUtil = new MaterialAdapter(this);
        Object.assign(this, materialUtil);

        let self = this;
        // 获取对象 A 的原型
        const utilPrototype = Object.getPrototypeOf(materialUtil);

        // 遍历原型的属性并复制到对象 B
        Object.getOwnPropertyNames(utilPrototype).forEach((prop) => {
        if (prop !== 'constructor') {
            this[prop] = utilPrototype[prop];
        }
        });

        this.onBeforeCompile = function (shader) {
            self['preCompileShader'](shader, materialParam);
        }

        this['setCustomKey'](materialParam);
        
    }
}